package database.datastructure;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class ExpressionEval {
	
	private Map<String, Integer> exprMap;
	private Map<String, Character> subExprMap;
	private ArrayList<String> conditionAttr;
	
	public ArrayList<String> getConditionAttr() {
		return conditionAttr;
	}

	public Map<String, Integer> evaluateExpression(String expr) {
		exprMap = new HashMap<String, Integer>();
		subExprMap = new HashMap<String, Character>();
		conditionAttr = new ArrayList<String>();
		int startPos = 0;
		int subExpStrtPnt = 0;
		int subExpEndPnt = 0;
		Character delimiter = 'a';
		if (expr.charAt(0) == '-') {
			//System.out.println("Starting with -");
			startPos = 1;
			subExpStrtPnt = 1;
			delimiter = '-';
		}
		
		if (expr.contains("+") || expr.contains("-")) {
			for (int i = startPos; i < expr.length(); i++) {
				if (expr.charAt(i) == '+' || expr.charAt(i) == '-') {
					subExpEndPnt = i;
					if (subExpEndPnt-subExpStrtPnt > 0) {
						if (delimiter == 'a')
							delimiter = '+';
						subExprMap.put(expr.substring(subExpStrtPnt, subExpEndPnt), delimiter);
						delimiter = expr.charAt(i);
						subExpStrtPnt = i+1;
					}
				} else {
					continue;
				}
			}
			subExprMap.put(expr.substring(subExpStrtPnt, expr.length()), delimiter);
			
			try {
				for (String curSubExp : subExprMap.keySet()) {
					if (subExprMap.get(curSubExp) == '+') {
						if (curSubExp.length() == 1) {
							exprMap.put(curSubExp, 1);
							conditionAttr.add(curSubExp);
						} else {
							//System.out.println(curSubExp);
							StringTokenizer strTok = new StringTokenizer(curSubExp, "*");
							while (strTok.hasMoreTokens()) {
								String key = strTok.nextToken();
								String value = strTok.nextToken();
								try {//expr Form = 2*A
									exprMap.put(value, Integer.parseInt(key));
									conditionAttr.add(value);
								} catch(Exception e) {//expr Form = A*2
									exprMap.put(key, Integer.parseInt(value));
									conditionAttr.add(key);
								}
							}
						}
					} else {
						if (curSubExp.length() == 1) {
							exprMap.put(curSubExp, 1);
							conditionAttr.add(curSubExp);
						} else {
							//System.out.println("In - : "+curSubExp);
							StringTokenizer strTok = new StringTokenizer(curSubExp, "*");
							while (strTok.hasMoreTokens()) {
								String key = strTok.nextToken();
								String value = strTok.nextToken();
								try {//expr Form = 2*A
									exprMap.put(value, -(Integer.parseInt(key)));
									conditionAttr.add(value);
								} catch(Exception e) {//expr Form = A*2
									exprMap.put(key, -(Integer.parseInt(value)));
									conditionAttr.add(key);
								}
							}
						}
					}
				}
			} catch(Exception e) {
				e.printStackTrace();
			}
		} else if (startPos == 1) {
			expr = expr.substring(1, expr.length()-1);
			StringTokenizer strTok = new StringTokenizer(expr, "*");
			while (strTok.hasMoreTokens()) {
				String key = strTok.nextToken();
				String value = strTok.nextToken();
				try {//expr Form = 2*A
					exprMap.put(value, -(Integer.parseInt(key)));
					conditionAttr.add(value);
				} catch(Exception e) {//expr Form = A*2
					exprMap.put(key, -(Integer.parseInt(value)));
					conditionAttr.add(key);
				}
			}
		} else {
			StringTokenizer strTok = new StringTokenizer(expr, "*");
			while (strTok.hasMoreTokens()) {
				String key = strTok.nextToken();
				String value = strTok.nextToken();
				try {//expr Form = 2*A
					exprMap.put(value, Integer.parseInt(key));
					conditionAttr.add(value);
				} catch(Exception e) {//expr Form = A*2
					exprMap.put(key, Integer.parseInt(value));
					conditionAttr.add(key);
				}
			}
		}
		return exprMap;
	}
}
